// poj2342
// 题意：给定一个n(<=6000)节点的树，每个节点都有一个权值，现在要选出
//       一个最大独立点集是得权值和最大。
//
// 题解：就是一个简单的树形dp。
//
// run: $exec < input
#include <iostream>
#include <cstring>

int const maxn = 6007;
int head[maxn], end_point[2 * maxn], next[2 * maxn];
int alloc;
bool not_root[maxn];
int rating[maxn];
int n;

void add_edge(int u, int v)
{
	end_point[alloc] = v; next[alloc] = head[u]; head[u] = alloc++;
}

void init()
{
	std::memset(head, 0, sizeof(head));
	std::memset(not_root, 0, sizeof(not_root));
	alloc = 2;
}

int f[maxn][2];

int dfs(int u)
{
	f[u][1] = rating[u];
	f[u][0] = 0;
	for (int p = head[u]; p; p = next[p]) {
		int v = end_point[p];
		dfs(v);
		f[u][1] += f[v][0];
		f[u][0] += std::max(f[v][0], f[v][1]);
	}
	return std::max(f[u][0], f[u][1]);
}

int main()
{
	while (std::cin >> n) {
		init();
		for (int i = 1; i <= n; i++)
			std::cin >> rating[i];
		for (int i = 1, l, k; i < n; i++) {
			std::cin >> l >> k;
			add_edge(k, l);
			not_root[l] = true;
		}
		int root = 1;
		for (int i = 1; i <= n; i++)
			if (!not_root[i]) { root = i; break; }
		std::cout << dfs(root) << '\n';
		int x, y; std::cin >> x >> y;
	}
}

